package com.agent.action.service.Impl;

import cn.hutool.core.convert.impl.UUIDConverter;
import com.agent.action.dataobject.PractiseCatalogDO;
import com.agent.action.dto.PractiseDTO;
import com.agent.action.entity.CatalogEntity;
import com.agent.action.entity.PractiseEntity;
import com.agent.action.mapper.PractiseCatalogMapper;
import com.agent.action.mapper.PractiseMapper;
import com.agent.action.param.PractiseParam;
import com.agent.action.service.PractiseService;
import com.agent.action.vo.PractiseVO;
import com.agent.action.vo.PractisesCatalogVO;
import com.agent.commons.errorcode.ControllerErrorCodeConstants;
import com.agent.commons.errorcode.ServiceErrorCodeConstants;
import com.agent.commons.exception.BaseException;
import com.agent.commons.other.ThreadLocal;
import com.agent.commons.utils.JacksonUtil;
import com.agent.commons.utils.MinIOUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import static com.agent.commons.errorcode.ServiceErrorCodeConstants.*;
import static com.agent.commons.errorcode.ControllerErrorCodeConstants.*;

import java.beans.Transient;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;

@Service
@Slf4j
public class PractiseServiceImpl implements PractiseService {

    @Resource
    private PractiseMapper practiseMapper;
    @Resource
    private PractiseCatalogMapper practiseCatalogMapper;
    /**
     * 返回图片存储路径
     * @param files
     * @return
     */
    @Override
    public List<String> loadPhoto(MultipartFile[] files) {
        List<String> urls=new ArrayList<>();
        for (MultipartFile file : files) {
            String url=MinIOUtil.makeFileName(UUID.randomUUID()+"_" +file.getOriginalFilename());
            try {
                String endUrl = MinIOUtil.uploadFile("practise", file, url);
                //将图片上传后的路径存入集合中
                urls.add(endUrl);
            } catch (Exception e) {
                log.error("文件上传失败",e);
                throw new BaseException(FILE_UPLOAD_DEFEAT);
            }
        }
        return urls;
    }

    @Override
    @Transactional
    public List<PractiseVO> loadPractise(PractiseParam practiseParam) {
        //获取用户Id
        String userId = ThreadLocal.getUserId();
        //获取practiseId
        String practiseId=practiseParam.getPractiseId();
        //获取为null，证明是新增
        if(practiseId==null) {
            //生成uuid
            practiseId = UUID.randomUUID().toString();
            //存储该题集号
            CatalogEntity catalogEntity = new CatalogEntity();
            catalogEntity.setPractiseId(practiseId);
            catalogEntity.setPractiseName(practiseParam.getPractiseName());
            catalogEntity.setUserId(userId);
            this.insertPractiseCatalog(catalogEntity);
            //存储题集具体内容
            for (PractiseEntity practise : practiseParam.getPractises()) {
                PractiseDTO practiseDTO = convertPractise(practise, practiseId);
                practiseMapper.insertPractise(practiseDTO);
            };
        }
        //如果不为空，则代表为更新
        else{
            //更新题集名称
            if(!this.updatePractiseCatalogName(practiseParam.getPractiseName(),practiseId)){
                throw new BaseException(ControllerErrorCodeConstants.USER_NOT_EXIST);
            }
            //获取原先题集题目号集合
            List<Long> ids = getIds(practiseId);
            List<Long> idList= new ArrayList<>();
            //更新题集具体内容
            for (PractiseEntity practise : practiseParam.getPractises()) {
                Long id = practise.getId();
                PractiseDTO practiseDTO = convertPractise(practise, practiseId);
                //id包含进行更新
                if(ids.contains(id)){
                    practiseMapper.updatePractise(practiseDTO);
                }else{
                    practiseMapper.insertPractise(practiseDTO);
                }
                idList.add(id);
            };
            //如果更新的题目中没有该题目则把原先的题目删除
            for(Long idOne : ids){
                if(!idList.contains(idOne)){
                    practiseMapper.deleteById(idOne);
                }
            }
        }
        return this.getPractises(practiseId);
    }
    @Override
    public List<PractisesCatalogVO> listPractisesCatalog(String userId) {
        return practiseMapper.getPractisesCatalog(userId);
    }

    @Override
    @Transactional
    public boolean deletePractisesCatalog(String catalogId) {
        //删除题集中对应的题目
        List<PractiseDTO> practises = practiseMapper.getPractises(catalogId);
        practises.forEach(practise -> {
            practiseMapper.deleteById(practise.getId());
        });
        return practiseCatalogMapper.deletePractisesCatalog(catalogId);
    }

    /**
     * 获取具体练习
     * @param practiseId
     * @return
     */
    @Override
    public List<PractiseVO> getPractises(String practiseId) {
        List<PractiseDTO> practises = practiseMapper.getPractises(practiseId);
        log.error("practises:{}",practises);
        return practises.stream().map(e -> {
            PractiseVO practiseVO = new PractiseVO();
            BeanUtils.copyProperties(e, practiseVO);
            log.error("practiseVO:{}",practiseVO);
            practiseVO.setOptions(JacksonUtil.readListValue(e.getOptions(), String.class));
            practiseVO.setPicture(JacksonUtil.readListValue(e.getPicture(), String.class));
            return practiseVO;
        }).toList();
    }

    @Override
    public boolean belongToUser(String practiseId) {
        log.error("belongToUser:{}",practiseId);
        String userId = practiseCatalogMapper.getUserId(practiseId);
        if(userId == null){
            throw new BaseException(CATALOG_NOT_EXIST);
        }
        return practiseCatalogMapper.getUserId(practiseId).equals(ThreadLocal.getUserId());
    }

    @Override
    public boolean containPractise(String practiseId) {
        return practiseMapper.getPractise(practiseId) != 0;
    }

    /**
     * 获取特定题集中的题目id
     * @param practiseId
     * @return
     */
    public List<Long> getIds(String practiseId){
        return practiseMapper.getIds(practiseId);
    }

    public PractiseDTO convertPractise(PractiseEntity practise,String practiseId){
        PractiseDTO practiseDTO = new PractiseDTO();
        practiseDTO.setPractiseId(practiseId);
        practiseDTO.setUserId(ThreadLocal.getUserId());
        if(practise.getId() != null) {
            practiseDTO.setId(practise.getId());
        }
        practiseDTO.setType(practise.getType());
        practiseDTO.setContent(practise.getContent());
        practiseDTO.setPicture(practise.getPicture()==null?"[]":JacksonUtil.writeValueAsString(practise.getPicture()));
        practiseDTO.setOptions(practise.getOptions()==null?"[]":JacksonUtil.writeValueAsString(practise.getOptions()));
        practiseDTO.setAnswer(practise.getAnswer());
        return practiseDTO;
    }

    public void insertPractiseCatalog(CatalogEntity catalogEntity){
        int i = practiseMapper.insertPractiseCatalog(catalogEntity);
        if(i==0){
            throw new BaseException(INSERT_ERROR);
        }
    }

    /**
     * 修改题集名称
     * @param name
     * @param practiseId
     */
    public boolean updatePractiseCatalogName(String name,String practiseId){
        return practiseCatalogMapper.updateName(name,practiseId)!=0;
    }
}
